import matplotlib.pylab as plt
import numpy as np
import pandas as pd
import seaborn as sns
from tqdm import tqdm
import color_get
# 调整图例legend的位置,可拖动
# leg=plt.legend()
# leg.set_draggable(state=True)
# https://blog.csdn.net/sunny_guang/article/details/112271555

# 绘制彩色的RGB柱状图
# x:数据
# y:x数据的频率
# width数据条宽度,根据情况加大或减小
# 图例标签
# 其中x,height,labels长度需要一致
# RGBA的范围可以自己拓展固定到某一范围或判断，进行定向随机颜色
def DrawColorfulbar(x, height, width, LB=None):
    plt.figure()
    for i in range(len(x)):
        RGB = []
        for j in range(3):
            RGB.append(np.random.randint(0, 255))
        if LB is not None:
            plt.bar(x=x[i], height=height[i], color=(RGB[0] / 255, RGB[1] / 255, RGB[2] / 255), width=width)
        else:
            plt.bar(x=x[i], height=height[i], color=(RGB[0] / 255, RGB[1] / 255, RGB[2] / 255), width=width)
    plt.legend()



# 对于两个数据每种指标的画多种比较图
# 直方图、散点图、折线走势比较图、合并走势比较图、箱线比较图
# 注意
# data1,2_Y输入为DataFrame,且其索引为datetime
def Compare_Draw(data1, data2, title1='标题一', title2='标题二', draw_function=[]):
    """
    :param data1: 两个具有相同列元素的DataFrame
    :param data2:
    :param title1:
    :param title2:
    :param draw_function: 绘制函数
    :return:
    """
    datas = [data1, data2]
    titles = [title1, title2]
    # 统计列数
    col_size = len(datas[0].columns)
    # 行数
    Row = col_size
    # 列数
    # 如果未输入绘制函数
    if not draw_function:
        draw_function = [plt.hist, plt.scatter, plt.plot]
    # 直方图,数据分布
    # 指标index
    print('绘制直方图:')
    for index in tqdm(range(col_size)):
        fig, axes = plt.subplots(1, 2, sharex=True, sharey=True)
        for col_index in range(2):
            # 直方图,数据分布
            # 柱状图,数据比较
            # https://blog.csdn.net/weixin_45520028/article/details/113924866
            # x:输入的数据
            # bins分成多少柱子
            # range:剔除掉大于或小于该范围的值,(minvalue,maxvalue)
            # rwidth:柱子间隔,0.8
            # normed:是否归一化
            # edgecolor:颜色
            # 列数据
            y = datas[col_index].iloc[:, index]
            # index时间索引
            x = y.index
            axes[col_index].hist(x=y, bins=30)
            axes[col_index].title.set_text(titles[col_index] + datas[col_index].iloc[:, index].name + '直方图')
        plt.subplots_adjust(wspace=0,hspace=0)

    # 散点,数据分布
    # 指标index
    print('绘制散点图:')
    for index in tqdm(range(col_size)):
        fig, axes = plt.subplots(1, 2, sharex=True, sharey=True)
        for col_index in range(2):
            # 列数据
            y = datas[col_index].iloc[:, index]
            # index时间索引
            x = pd.to_datetime(y.index)
            axes[col_index].scatter(x=x, y=y)
            axes[col_index].title.set_text(titles[col_index] + datas[col_index].iloc[:, index].name + '散点图')
        plt.subplots_adjust(wspace=0,hspace=0)
    # 直线走势比较图,数据分布
    # 指标index
    print('绘制折线走势比较图:')
    for index in tqdm(range(col_size)):
        fig, axes = plt.subplots(1, 2, sharex=True, sharey=True)
        for col_index in range(2):
            # 列数据
            y = datas[col_index].iloc[:, index]
            # index时间索引
            x = pd.to_datetime(y.index)
            axes[col_index].plot(x, y)
            axes[col_index].title.set_text(titles[col_index] + datas[col_index].iloc[:, index].name + '折线走势图')
        plt.subplots_adjust(wspace=0,hspace=0)

    # 合并折线走势图图
    print('绘制合并走势比较图:')
    for index in tqdm(range(col_size)):
        fig=plt.figure()
        for col_index in range(2):
            # 列数据
            y = datas[col_index].iloc[:, index]
            # index时间索引
            x = pd.to_datetime(y.index)
            plt.plot(x, y, label=titles[col_index])
        leg=fig.legend()
        leg.set_draggable(state=True)
        plt.title(datas[col_index].iloc[:, index].name + '折线走势图')
    # 绘制箱线图
    print('绘制箱线比较图:')
    for index in tqdm(range(col_size)):
        fig=plt.figure()
        Y=[]
        for col_index in range(2):
            # 列数据
            y = datas[col_index].iloc[:, index]
            Y.append(y)
            # index时间索引
            # x = pd.to_datetime(y.index)
        df=pd.DataFrame(Y,index=titles).T
        df.boxplot()
        # plt.xticks(range(3),labels=[''].extend(titles))
        # fig.legend()
        plt.title(datas[col_index].iloc[:, index].name + '箱线图')


# 两个矩阵相同列之间的数据比较
# 1、会将相同的指标调用Compare_Draw
# 2、做指标相关性热力图
def DataFrame_Compare_Draw(df1, df2, title1='标题一', title2='标题二'):
    df1 = pd.DataFrame(df1)
    df2 = pd.DataFrame(df2)
    # 获取相同的列
    df1_col = df1.columns.values
    df2_col = df2.columns.values
    Same_col = []
    for i in df1_col:
        if df2_col.__contains__(i):
            Same_col.append(i)
    # 绘制直方图,走势图,箱线图
    # for i in Same_col:
    #     Compare_Draw(data1_Y=df1[i],data2_Y=df2[i],title1=title1,title2=title2)
    Compare_Draw(data1_Y=df1[Same_col], data2_Y=df2[Same_col], title1=title1, title2=title2)
    # 绘制相关性热力图
    corr_str='指标相关性'
    # 首先是相同的列的相关图
    Draw_Corr_Map(df1[Same_col])
    plt.title(title1+corr_str)
    Draw_Corr_Map(df2[Same_col])
    plt.title(title1+corr_str)
    # 各自的相关性热力图
    Draw_Corr_Map(df1)
    plt.title(title1+corr_str)
    Draw_Corr_Map(df2)
    plt.title(title2+corr_str)


# 绘制相关性热力图
# https://zhuanlan.zhihu.com/p/364624304
# https://www.freesion.com/article/5253316630/
def Draw_Corr_Map(data_df,show_value:bool=False):
    """
    绘制指标之间的相关性热力图
    :param data_df: 矩阵DataFrame格式
    :param show_value: 热力图上是否显示相关性指标
    :return:df_coor:相关性矩阵
    """
    # 求相关性,Corr与Cov的关系
    # https://zhidao.baidu.com/question/1884090072477073588.html
    df_coor = data_df.corr()
    size = len(data_df.columns)
    plt.subplots(figsize=(size, size), facecolor='w')  # 设置画布大小，分辨率，和底色
    cmaps=color_example.Get_cmaps()
    # 绘制颜色的选择
    # https://blog.csdn.net/yzxnuaa/article/details/89528971
    # 绘制每种颜色的样式
    for type,colors in tqdm(cmaps.items()):
        for color in colors:
            # 设置画布大小，分辨率，和底色
            plt.subplots(facecolor='w')
            # 绘制
            # annot为热力图上显示数据；fmt='.2g'为数据保留两位有效数字,square呈现正方形，vmax最大值为1
            fig = sns.heatmap(df_coor, annot=show_value, vmax=1, square=True, cmap=color,
                      fmt='.2g')

    # fig.get_figure().savefig('df_corr.png', bbox_inches='tight', transparent=True)  # 保存图片
    # bbox_inches让图片显示完整，transparent=True让图片背景透明
    return df_coor


# 创建可移动的图例
def Move_Able_Legend():
    leg=plt.legend()
    leg.set_draggable(state=True)
    return leg

# 检查时间完整性
# 日期、小时、分钟
def Integrity_of_time(datas=['dataframe列表'],cols=['日期','小时','分钟'],titles=['输入标题列表']):
    for i in range(len(cols)):
        plt.figure()
        for j in range(len(datas)):
            datas[j][cols[i]].plot(label=titles[j])
        Move_Able_Legend()
        plt.title(cols[i]+'完整性')

# 绘制饼图
def Draw_pie(list_count,labels:[str]):
    """
        # patches, l_text, p_text = plt.pie([zeros, ones],
    #                                   labels=[
    #                                       '类别0',
    #                                       '类别1'],
    #                                   explode=[0, 0.1],
    #                                   autopct="(%1.2f%%)")
    # plt.figure()
    # plt.pie(list_count,labels=labels,)
    :param list_count:
    :param labels:
    :return:
    """


# 通过给定的DataFrame绘制
def DataFrame_Draw(data,title:str):
    plt.figure()
    data.boxplot()
    plt.title(title+'箱线图')
    data.plot()
    Move_Able_Legend()
    plt.title(title+'折线图')
    # 若只有两列,绘制散点图
    if len(data.columns)==2:
        lables_two=data.columns.values
        plt.figure()
        plt.scatter(x=data.iloc[:,0],y=data.iloc[:,1])
        plt.xlabel=lables_two[0]
        plt.ylabel=lables_two[1]



def Scatter_Compare(array1,array2):
    cmaps=color_get.Get_cmaps()
    # for type,colors in tqdm(cmaps.items()):
    #     for color in colors:
    #         plt.figure()
    #         plt.scatter(array1,array2,cmap=color)

def Matrix_Scatter(df):
    """
    绘制矩阵散点图
    :param df:
    :return:
    """
    sns.pairplot(df, hue='continent')

# 聚类未聚类的，标签为-1

# np.where([bool])
# 可以获取索引值


